#pragma once

#include "actuator/class_custom.h"
#include <memory>
#include <yaml-cpp/yaml.h>
#include <algorithm>

namespace actuator
{

class GetParams
{
public:
    virtual ~GetParams() = default;
    virtual void Init(std::string &file_name, std::shared_ptr<boost::circular_buffer<st_par>> &param_buffer) = 0;

    virtual bool GetParam(const std::string &name, float &value) = 0;
    virtual bool GetParam(const std::string &name, bool  &value) = 0;
    virtual bool GetParam(const std::string &name, int   &value) = 0;
    virtual bool GetParam(const std::string &name, std::string &value) = 0;
    
    virtual void Append(const std::shared_ptr<GetParams>&) {}
    virtual void Remove(const std::shared_ptr<GetParams>&) {}

    virtual void LoadAMRParams(const std::string &name, std::vector<SteerParams> &params) {}
    virtual YAML::Node GetYaml(const std::string &name) {YAML::Node node; return node;}

    std::vector<SteerParams> steer_params;
};

class LoadYamlFile : public GetParams
{
public:
    void Init(std::string &file_name, std::shared_ptr<boost::circular_buffer<st_par>> &param_buffer) override;

    bool GetParam(const std::string &name, float &value) override;
    bool GetParam(const std::string &name, bool  &value) override;
    bool GetParam(const std::string &name, int   &value) override;
    bool GetParam(const std::string &name, std::string &value) override;

    YAML::Node GetYaml(const std::string &name) override;
private:
    YAML::Node actuator_params_;
};

class LoadVCS : public GetParams
{
public:
    void Init(std::string &file_name, std::shared_ptr<boost::circular_buffer<st_par>> &param_buffer) override;

    bool GetParam(const std::string &name, float &value) override;
    bool GetParam(const std::string &name, bool  &value) override;
    bool GetParam(const std::string &name, int   &value) override;
    bool GetParam(const std::string &name, std::string &value) override;
};

class GetParamClient : public GetParams
{
public:
    void Init(std::string &file_name, std::shared_ptr<boost::circular_buffer<st_par>> &param_buffer) override;

    bool GetParam(const std::string &name, float &value) override;
    bool GetParam(const std::string &name, bool  &value) override;
    bool GetParam(const std::string &name, int   &value) override;
    bool GetParam(const std::string &name, std::string &value) override;

    void Append(const std::shared_ptr<GetParams>& s) override;
    void Remove(const std::shared_ptr<GetParams>& s) override;

    void LoadAMRParams(const std::string &name, std::vector<SteerParams> &params) override;

private:
    std::vector<std::shared_ptr<GetParams>> ptr_params_;
};

}
